﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Windows.Forms;

namespace MagicCove
{
    public partial class DeckEditorForm : Form
    {
        private List<MagicCard> deck;
        private List<MagicCard> sideboard;
        private bool noFirstSearch = true; //true until first search is made

        public DeckEditorForm()
        {
            InitializeComponent();
        }

        public DeckEditorForm(string[] args)
        {
            InitializeComponent();
            MessageBox.Show("This is my first arg: " + args[0]);
        }
        private void getCardInfoB_Click(object sender, EventArgs e)
        {
            if (noFirstSearch)
            {
                cardTextOutputTB.Text = "Establishing connection to the server...\r\n\r\nPlease be patient, this may take several seconds...";
                noFirstSearch = false;
            }
            else
                cardTextOutputTB.Text = "Please wait while the data is requested from the server...";
            cardTextOutputTB.Update();
            String cardAddress = "http://www.magiccards.info/query?q=" + cardNameInputTB.Text + "&v=card&s=cname";
            // used to build entire input
            StringBuilder sb = new StringBuilder();

            // used on each read operation
            byte[] buf = new byte[8192];

            // prepare the web page we will be asking for
            HttpWebRequest request = (HttpWebRequest)
                WebRequest.Create(cardAddress);
//Need to try catch next command to check internet. Catch display message you are not connected to the internet.
            Stream resStream;
            try
            {
                // execute the request
                HttpWebResponse response = (HttpWebResponse)
                    request.GetResponse();
                // we will read data via the response stream
                resStream = response.GetResponseStream();
            }
            catch
            {
                MessageBox.Show("You are not connected to the internet.");
                return;
            }

            string tempString = null;
            int count = 0;

            do
            {
                // fill the buffer with data
                count = resStream.Read(buf, 0, buf.Length);

                // make sure we read some data
                if (count != 0)
                {
                    // translate from bytes to ASCII text
                    tempString = Encoding.ASCII.GetString(buf, 0, count);

                    // continue building the string
                    sb.Append(tempString);
                }
            }
            while (count > 0); // any more data to read?

            // print out page source
            String pageSC = sb.ToString();
            //Card Info
            int infoStartIndex = pageSC.IndexOf("<p>") + 3;
            int infoEndIndex = pageSC.IndexOf("</p>");
            if (infoEndIndex - infoStartIndex > 0)
                cardInfoOutputTB.Text = pageSC.Substring(infoStartIndex, infoEndIndex - infoStartIndex);
            else
                cardInfoOutputTB.Text = "Not a valid card";

            //Card Name
            int cNStartIndex = pageSC.IndexOf("alt")+4;
            int cNEndIndex = pageSC.IndexOf("<p>");
            //cardNameOut.Text = cNStartIndex.ToString();
            try
            {
                String cardNSubString = pageSC.Substring(cNStartIndex, cNEndIndex);
                int realCNSI = cardNSubString.IndexOf("alt");
                cardNSubString = cardNSubString.Substring(realCNSI + 5, 250);
                realCNSI = 0;
                int realCNEI = cardNSubString.IndexOf("\"");
                if (realCNEI - realCNSI > 0)
                    cardNameOutputTB.Text = cardNSubString.Substring(realCNSI, realCNEI);
                else
                    cardNameOutputTB.Text = "Not a valid card";
            }
            catch
            {
            }

            //Card Text
            try
            {
                int cTSI = pageSC.IndexOf("<p ") + 20;
                int cTEI = pageSC.IndexOf("</b></p>");
                String stringToDispInDesc = pageSC.Substring(cTSI, cTEI - cTSI);
                int tmpIndex;
                String tmpSubString1;
                String tmpSubString2;
                while (stringToDispInDesc.IndexOf("<br>") > 0)
                {
                    tmpIndex = stringToDispInDesc.IndexOf("<br>");
                    tmpSubString1 = stringToDispInDesc.Substring(0, tmpIndex);

                    tmpSubString2 = stringToDispInDesc.Substring(tmpIndex + 4, stringToDispInDesc.Length - tmpIndex - 4);
                    stringToDispInDesc = tmpSubString1 + "\r\n" + tmpSubString2;
                }
                cardTextOutputTB.Text = stringToDispInDesc;
            }
            catch
            {
                cardTextOutputTB.Text = "No card description found.";
            }
            //card rulings
            try
            {
                String cardRulingsS = pageSC.Substring(pageSC.IndexOf("Gatherer Card Rulings"));
                cardRulingsS = cardRulingsS.Substring(cardRulingsS.IndexOf("<ul>") + 4, cardRulingsS.IndexOf("</ul>") - cardRulingsS.IndexOf("<ul>") - 4);
                //"interpret" html <b> and <li>
                cardRulingsS = cardRulingsS.Replace("<b>", "");
                cardRulingsS = cardRulingsS.Replace("</b>", "");
                cardRulingsS = cardRulingsS.Replace("<li>", "");
                cardRulingsS = cardRulingsS.Replace("</li>", "\r\n\r\n");
                cardRulingsTB.Text = cardRulingsS;
            }
            catch { }
            //Picture Display
            try
            {
                //Get Url
                int picSI = pageSC.IndexOf("<img src") + 10;
                int picEI = pageSC.IndexOf("<p>");
                String picTempSubS1 = pageSC.Substring(picSI, picEI - picSI);
                picSI = picTempSubS1.IndexOf("<img src") + 10;
                String picTempSubS2 = picTempSubS1.Substring(picSI, picTempSubS1.Length - picSI);
                picEI = picTempSubS2.IndexOf("\"");
                String picUrl = picTempSubS2.Substring(0, picEI);
                //Pic Disp
                System.Net.WebClient source = new System.Net.WebClient();
                Stream myData = source.OpenRead(picUrl);
                System.Drawing.Bitmap cardPic = new System.Drawing.Bitmap(myData);
                myData.Close();
                //create a new Bitmap the size of the new image
                Bitmap cPMod = new Bitmap(cardImage.Width, cardImage.Height);
                //create a new graphic from the Bitmap
                Graphics graphic = Graphics.FromImage((Image)cPMod);
                graphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
                //draw the newly resized image
                graphic.DrawImage(cardPic, 0, 0, cardImage.Width, cardImage.Height);
                //dispose and free up the resources
                graphic.Dispose();
                cardImage.Image = cPMod;
            }
            catch
            {
            }
            if (cardInfoOutputTB.Text.Equals("Not a valid card"))
            {
                cardNameOutputTB.Text = "Could not find any match";
                cardImage.Image = MagicCove.Properties.Resources.magicCardBackSized;
            }
        }
        private void addCardToDG(int number, string name, bool sideboard)
        {//assumes there is always a free row
            deckDisplayDGV.Rows.Insert(deckDisplayDGV.Rows.Count - 1, 1);
            deckDisplayDGV["numberTBC", deckDisplayDGV.Rows.Count - 2].Value = number;
            deckDisplayDGV["cardNameTBC", deckDisplayDGV.Rows.Count - 2].Value = name;
            deckDisplayDGV["sideboardCBC", deckDisplayDGV.Rows.Count - 2].Value = sideboard;
        }
        private void setDataForDG()
        {//uses current deck and sideboard data to set the DataGrids values
            List<MagicCard> tempDeck = new List<MagicCard>(deck);
            while (tempDeck.Count != 0)
            {
                int cardCount = 1;
                for (int i = 1; i < tempDeck.Count; i++)
                    if (tempDeck[i].CardName.Equals(tempDeck[0].CardName))
                    {
                        cardCount++;
                        tempDeck.RemoveAt(i);
                        i--;//so we don't skip, since we just removed want to check same location again
                    }
                addCardToDG(cardCount, tempDeck[0].CardName, false);
                tempDeck.RemoveAt(0);
            }
            List<MagicCard> tempSideboard = new List<MagicCard>(sideboard);
            while (tempSideboard.Count != 0)
            {
                int cardCount = 1;
                for (int i = 1; i < tempSideboard.Count; i++)
                    if (tempSideboard[i].CardName.Equals(tempSideboard[0].CardName))
                    {
                        cardCount++;
                        tempSideboard.RemoveAt(i);
                        i--;//so we don't skip, since we just removed want to check same location again
                    }
                addCardToDG(cardCount, tempSideboard[0].CardName, true);
                tempSideboard.RemoveAt(0);
            }
        }
        private bool checkDeckValidity()
        {//check names by searching and seeing if it returns the same 
            return true;
        }
        private void importDeckB_Click(object sender, EventArgs e)
        {
            importDeckOFD.ShowDialog();
            deckDisplayDGV.Rows.Clear();
            try
            {
                // create reader & open file
                TextReader deckFileTR = new StreamReader(importDeckOFD.FileName);
                // read the text file
                string deckO = deckFileTR.ReadToEnd();
                // close the stream
                deckFileTR.Close();
                MagicField mF = new MagicField(GameFunctions.stripDeck(deckO));
                deck = mF.deck;
                sideboard = mF.sideboard;
                if (mF.deckName.Equals(""))
                    deckNameT.Text = importDeckOFD.FileName.Substring(importDeckOFD.FileName.LastIndexOf("\\") + 1, importDeckOFD.FileName.LastIndexOf(".") - importDeckOFD.FileName.LastIndexOf("\\") - 1);
                else
                    deckNameT.Text = mF.deckName;
                setDataForDG();
            }
            catch
            {
                MessageBox.Show("Please enter valid file location.");
            }

        }

        private void cardNameInputTB_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Enter)
            {
                getCardInfoB_Click(sender, (EventArgs)e);
                e.Handled = true;
            }
        }

        private void advancedSearchB_Click(object sender, EventArgs e)
        {
            MessageBox.Show("This feature is not yet supported ~!~. It will be incorporated in a future release.");
        }

        private void saveDeckB_Click(object sender, EventArgs e)
        {//eventualy add a progress bar to saving (with a background worker)
            //saveDeckSFD.FileName = deckNameT.Text;
            saveDeckSFD.ShowDialog();
            MessageBox.Show(saveDeckSFD.FileName);
            //add an and before if which prompts the user whether to check validity or not (like: if (dialog == false || (dialog == true && checkDeckValidity))~!~
            if (checkDeckValidity())
            {
                try
                {
                    TextWriter deckFileTW = new StreamWriter(saveDeckSFD.FileName);
                    deckFileTW.WriteLine(":" + deckNameT.Text);
                    //handle mainboard
                    for (int i = 0; i < deckDisplayDGV.Rows.Count - 2; i++) //last row is empty
                    {
                        if (!(bool)deckDisplayDGV["sideboardCBC", i].Value)
                            deckFileTW.WriteLine(deckDisplayDGV["numberTBC", i].Value + "-" + deckDisplayDGV["cardNameTBC", i].Value);
                    }
                    //handle sideboard
                    deckFileTW.WriteLine("Sideboard");
                    for (int i = 0; i < deckDisplayDGV.Rows.Count - 2; i++) //last row is empty
                    {
                        if ((bool)deckDisplayDGV["sideboardCBC", i].Value)
                            deckFileTW.WriteLine(deckDisplayDGV["numberTBC", i].Value + "-" + deckDisplayDGV["cardNameTBC", i].Value);
                    }
                    deckFileTW.Close();
                }
                catch
                {
                    ;
                }
            }
            MessageBox.Show("Saving complete.");
        }

        private void addCardToDeckB_Click(object sender, EventArgs e)
        {
            if (!cardNameOutputTB.Text.Equals("Could not find any match") && !cardNameOutputTB.Text.Equals(""))
                addCardToDG(1, cardNameOutputTB.Text, false);
        }

        private void cardImage_DoubleClick(object sender, EventArgs e)
        {
            if (!cardNameOutputTB.Text.Equals("Could not find any match") && !cardNameOutputTB.Text.Equals(""))
                addCardToDG(1, cardNameOutputTB.Text, false);
        }

        private void runBasicAnalyticsB_Click(object sender, EventArgs e)
        {
            if (deck == null)
                return;
            foreach (MagicCard mC in deck)
                GameFunctions.downloadCardData(mC);
            //do more stuff
            throw new NotImplementedException("RDA");
        }
    }
}
